package sv.gob.mh.dgii.common;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

@SuppressWarnings("unchecked")
public class GeneralUtils {

	static Log log = LogFactory.getLog(GeneralUtils.class);

	/**
	 * 
	 * @param str
	 * @param lookup
	 * @return true if str is contained into lookup
	 */
	public static boolean in(String str, List lookup) {
		for (Iterator iter = lookup.iterator(); iter.hasNext();) {
			String temp = (String) iter.next();
			if (temp.equals(str))
				return true;
		}
		return false;
	}

	/**
	 * union algebra de conjuntos
	 * 
	 * @param one
	 * @param two
	 * @return a List with all Strings in one contained with two
	 */
	public static List unionList(List one, List two) {
		List result = new ArrayList();

		for (Iterator iter = one.iterator(); iter.hasNext();) {
			String str = (String) iter.next();
			if (in(str, two)) {
				result.add(str);
			}
		}
		return result;
	}

	/**
	 * do I have to explain ;)
	 * 
	 * @param lst
	 * @return
	 */
	public static String[] toStringArray(List lst) {
		String[] str = new String[lst.size()];
		int i = 0;
		for (Iterator iter = lst.iterator(); iter.hasNext(); i++) {
			str[i] = iter.next().toString();
		}
		return str;
	}

	/**
	 * 
	 * menos del algebra de conjuntos
	 * 
	 * @param conj
	 * @param minus
	 * @return
	 */
	public static List minusList(List<String> conj, List<String> minus) {
		List<String> copy = new ArrayList<String>();
		copy.addAll(conj);

		Collections.copy(copy, conj);

		for (String str : copy) {
			copy.remove(str);
		}

		return copy;
	}

	public static Date getFormattedDate(String date) {
		SimpleDateFormat sdf = new SimpleDateFormat();
		sdf.applyPattern(Constants.DATE_PATTERN);
		Date dt = null;
		try {
			dt = sdf.parse(date);
		} catch (Exception e) {
			log.debug("No se pudo efectuar la conversion: '" + date + "'");
		}
		return dt;
	}

	public static String getFormattedDate(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat();
		sdf.applyPattern(Constants.DATE_PATTERN);
		String dateFormat = null;
		try {
			dateFormat = sdf.format(date);
		} catch (Exception e) {
			log.debug("No se pudo efectuar la conversion: '" + date
					+ "' , formato: '" + Constants.DATE_PATTERN + "'");
		}
		return dateFormat;
	}

	public static String getFormattedDate(Date date, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat();
		sdf.applyPattern(format);
		String dateFormat = null;
		try {
			dateFormat = sdf.format(date);
		} catch (Exception e) {
			log.debug("No se pudo efectuar la conversion: '" + date
					+ "' , formato: '" + Constants.DATE_PATTERN + "'");
		}
		return dateFormat;
	}

	public static Date getFormattedDate(String date, String format) {

		DateTimeFormatter fmt = DateTimeFormat.forPattern(format);
		log.debug("Entrando en getFormattedDate: '" + date + "' , formato: '"
				+ format + "'");
		Date dt = null;
		DateTime dateTime = null;

		try {
			dateTime = fmt.parseDateTime(date);
			dt = new Date(dateTime.getMillis());

		} catch (Exception e) {
			log.debug("No se pudo efectuar la conversion: '" + date
					+ "' , formato: '" + format + "'");
		}
		return dt;
	}

	public static String iStreamToString(InputStream in) throws IOException {
		StringBuffer out = new StringBuffer();
		byte[] b = new byte[4096];
		for (int n; (n = in.read(b)) != -1;) {
			out.append(new String(b, 0, n));
		}
		return out.toString();
	}

	public static String lpadS(String valueToPad, String filler, int size) {
		StringBuilder builder = new StringBuilder();

		while (builder.length() + valueToPad.length() < size) {
			builder.append(filler);
		}
		builder.append(valueToPad);
		return builder.toString();
	}

	public static String lpadR(String valueToPad, String filler, int size) {
		StringBuilder builder = new StringBuilder();
		builder.append(valueToPad);
		
		while (builder.length() < size) {
			builder.append(filler);
		}		
		return builder.toString();
	}
	
	public static double round(double d, int decimalPlace) {

		BigDecimal bd = new BigDecimal(Double.toString(d));
		bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
		return bd.doubleValue();
	}

	public static double round(double d) {

		BigDecimal bd = new BigDecimal(Double.toString(d));
		bd = bd.setScale(Constants.DECIMAL_PLACES, BigDecimal.ROUND_HALF_UP);
		return bd.doubleValue();
	}

	public static double round(BigDecimal d) {

		d = d.setScale(Constants.DECIMAL_PLACES, BigDecimal.ROUND_HALF_UP);
		return d.doubleValue();
	}

	public static String getFormattedNit(String nit) {
		String returnNit = nit;
		if (returnNit != null && returnNit.length() == 14) {
			returnNit = returnNit.substring(0, 4) + "-"
					+ returnNit.substring(4, 10) + "-"
					+ returnNit.substring(10, 13) + "-"
					+ returnNit.substring(13);
		}
		return returnNit;
	}
	public static String getFormattedTel(String telefono) {
		String returnTel = telefono;
		       returnTel= returnTel.trim();
		if(Utils.isNullOrEmpty(returnTel))return returnTel=" ";
		if (returnTel.length() == 8) {
			returnTel = returnTel.substring(0, 4) + "-"
					+ returnTel.substring(4, 8);
					
		}else {
			returnTel = returnTel.substring(0, 3) + "-"
			+ returnTel.substring(3, 7);
		}
		return returnTel;
	}

	public static String getFormattedNrc(String nrc) {
		if(Utils.isNullOrEmpty(nrc))return nrc;
		String returnNrc = nrc.trim();
		if (returnNrc != null && returnNrc.length() > 1) {
			returnNrc = returnNrc.substring(0, returnNrc.length() - 1)
					+ "-"
					+ returnNrc.substring(returnNrc.length() - 1, returnNrc
							.length());
		}
		return returnNrc;
	}

	
	public static String createKeyChainQuoteComaSeparated(List<?> objects,
			String property) throws IllegalAccessException,
			InvocationTargetException, NoSuchMethodException {
		String keyChain = "";

		for (Iterator iter = objects.iterator(); iter.hasNext();) {
			String value = org.apache.commons.beanutils.BeanUtils.getProperty(iter, property);

			if (iter.hasNext()) {
				keyChain += Constants.QUOTATION_MARK + value
						+ Constants.QUOTATION_MARK + Constants.COMMA;
			} else {
				keyChain += Constants.QUOTATION_MARK + value
						+ Constants.QUOTATION_MARK;
			}

		}

		return keyChain;
	}
	
	public static boolean isNullOrEmpty(Object obj) {
		if (obj == null || obj.toString().length() < 1 || obj.toString().equals(Constants.EMPTY_STRING))
			return true;
		return false;
	}

	public static boolean isNullOrEmptyOrZero(Object obj) {
		if (obj == null
				|| obj.toString().length() < 1
				|| obj.toString().equals(Constants.EMPTY_STRING)
				|| ((obj instanceof Long && obj.equals(0L)) || (obj instanceof Integer && obj.equals(0)) || (obj instanceof Float && obj.equals(0.00)) || (obj instanceof Double && obj
						.equals(0.00)))) {
			return true;
		}

		return false;
	}

}// class
